package com.dream.technology.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dream.technology.data.WisdomWeChatRequestLogEntity;
import lombok.extern.slf4j.Slf4j;
import net.logstash.logback.marker.LogstashMarker;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

import static net.logstash.logback.marker.Markers.append;

/**
 * 使用aop记录日志信息
 * 
 * @author chen
 *
 */
@Slf4j
@Aspect
@Component
public class RequestLogAspect {





    @Pointcut("execution(* com.dream.technology.controller..*.*(..))")
    public void pointcutController() {
    }

    @Around("pointcutController()")
    public Object pointCut(ProceedingJoinPoint joinPoint) throws Throwable {


        log.info("进入环绕切面before。。。。。。");
        WisdomWeChatRequestLogEntity aopLog = new WisdomWeChatRequestLogEntity();

        // 日志记录类
        long beginTime = System.currentTimeMillis();
        // 从切面织入点处通过反射机制获取织入点处的方法
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String requestURI = request.getRequestURI();
        String remoteAddr = request.getRemoteAddr();
        String requestMethod = request.getMethod();
        String declaringTypeName = joinPoint.getSignature().getDeclaringTypeName();
        String methodName = joinPoint.getSignature().getName();
        // 将参数所在的数组转换成json
        Object[] args = joinPoint.getArgs();
        String requestParam = "";
        try {
            requestParam = JSONObject.toJSONString(args);
        } catch (Exception e) {
            requestParam = "[json error]";
        }


        LogstashMarker markers = append("request_url", requestURI)
                .and(append("remote_ip", remoteAddr))
                .and(append("request_method", requestMethod))
                .and(append("target_class", declaringTypeName))
                .and(append("target_method", methodName))
                .and(append("params", requestParam));

        aopLog.setSource("wechat").setUrl(requestURI).setClientIp(remoteAddr).setRequestMethod(requestMethod)
                .setClassName(declaringTypeName).setMethodName(methodName).setRequestParam(requestParam);


        log.info(append("request",aopLog).and(append("request.request_params",args)),"start");
        Object result = "";
        try{
            result = joinPoint.proceed();
        }catch (Exception ex){
            //代码异常处理日志
            // 执行时长(毫秒)
            long time = System.currentTimeMillis() - beginTime;
            // 异步记录日志


            log.info(append("request",aopLog), ex.getMessage());
            throw ex;
        }
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        String ret = JSON.toJSONString(result);
        aopLog.setRtnData(ret).setTime(time);

        // 异步记录日志
//        log.info("{\"request_url\":{},\"params\":{},\"response_\":{},\"exe_use_time\":{}}",
//                requestURI,requestParam,result,time);
//        log.info(append("request",aopLog), "complete");
        log.info(append("request",aopLog).and(append("request.response_body",result))
                .and(append("request.request_params",args)),"complete");

        return result;
    }


}
